﻿/********************************************************************************
  * @file    project.cpp
  * @author  Lun Li
  * @version V1.5.0
  * @date    2022.4.10
  * @brief   This file provides all the Project functions.
  *******************************************************************************/

#include "project.h"

Project::Project(const QString &projectName,
                     const QString &projectPath,
                     QSettings* projectFile,
                     QObject *parent)
    : QStandardItemModel(parent),
      m_projectName(projectName),
      m_projectPath(projectPath),
      projectSaveFile(projectFile)
{
    qRegisterMetaType<Project*>("Project*");
    projectFile->setParent(this);
    m_topItem = new ProjectItem(m_projectName, ProjectItem::Project, nullptr);
    appendRow(m_topItem);
    loadProject();
}

void Project::addSource(Source *newFile)
{
    m_fileList.append(newFile);
    ProjectItem *curItem = new ProjectItem(newFile->fileName(), ProjectItem::NoCompiled, newFile);
    m_topItem->appendRow(curItem);
    newFile->setProjectItem(curItem);
    saveProject();
}

void Project::removeSource(Source *file)
{
    if (!file) {
        return;
    }
    if (!file->projectItem()) {
        return;
    }
    removeRow(file->projectItem()->index().row(), file->projectItem()->index().parent());
    m_fileList.removeOne(file);
    file->deleteLater();
    saveProject();
}

void Project::saveProject()
{
    projectSaveFile->beginGroup("Sources");
    projectSaveFile->remove("");
    for (Source *file : m_fileList) {
        projectSaveFile->setValue(file->fileName(),
                                  QDir(m_projectPath).relativeFilePath(file->filePath()) + ',' +
                                  QString::number(file->projectItem()->itemType()) + ',' +
                                  (file->compiledFilePath().isEmpty() ? QString() : QDir(m_projectPath).relativeFilePath(file->compiledFilePath())) + ',' +
                                  (file->waveFilePath().isEmpty() ? QString() : QDir(m_projectPath).relativeFilePath(file->waveFilePath())));
    }
    projectSaveFile->endGroup();
}

void Project::loadProject()
{
    projectSaveFile->beginGroup("Sources");
    for (const QString &key : projectSaveFile->childKeys()) {
        QStringList value = projectSaveFile->value(key).toString().split(',');
        value.resize(4);
        const QString path = QDir(m_projectPath).absoluteFilePath(value.at(0));
        ProjectItem::TreeItemType itemType = ProjectItem::TreeItemType(value.at(1).toInt());
        Source *curFile = new Source(path, false, this);
        curFile->setCompiledFilePath(value.at(2).isEmpty() ? QString() : QDir(m_projectPath).absoluteFilePath(value.at(2)));
        curFile->setWaveFilePath(value.at(3).isEmpty() ? QString() : QDir(m_projectPath).absoluteFilePath(value.at(3)));
        m_fileList.append(curFile);
        ProjectItem *curItem = new ProjectItem(curFile->fileName(), itemType, curFile);
        m_topItem->appendRow(curItem);
        curFile->setProjectItem(curItem);
    }
    projectSaveFile->endGroup();
}

const ProjectItem *Project::topItem() const
{
    return m_topItem;
}

QString Project::compilePath() const
{
    return m_projectPath + "/compile";
}

QString Project::sourcePath() const
{
    return m_projectPath + "/src";
}

const QString &Project::projectName() const
{
    return m_projectName;
}

void Project::setProjectName(const QString &newProjectName)
{
    m_projectName = newProjectName;
}

const QString &Project::projectPath() const
{
    return m_projectPath;
}

void Project::setProjectPath(const QString &newProjectPath)
{
    m_projectPath = newProjectPath;
}

ProjectItem *Project::itemFromIndex(const QModelIndex &index) const
{
    return (ProjectItem *)(QStandardItemModel::itemFromIndex(index));
}

const QList<Source *> &Project::fileList() const
{
    return m_fileList;
}
